using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class EnemySpawner : MonoBehaviour
{
    // 单例模式
    public static EnemySpawner Instance { get; private set; }
    
    [Header("生成设置")]
    public GameObject[] enemyPrefabs;
    public float spawnRate = 2f;
    public float spawnRateIncrease = 0.1f; // 每波增加的生成速度
    public int maxEnemiesOnScreen = 10;
    
    [Header("生成区域")]
    public float spawnHeight = 6f;
    public float spawnWidth = 8f;
    public Vector2 spawnCenter = Vector2.zero;
    
    [Header("波次设置")]
    public bool useWaveSystem = true;
    public int enemiesPerWave = 5;
    public float timeBetweenWaves = 3f;
    
    [Header("编队设置")]
    public bool useFormation = true; // 是否按编队批量生成
    public FormationType formationType = FormationType.Grid;
    public int formationRows = 3;
    public int formationColumns = 4;
    public float formationSpacingX = 0.9f;
    public float formationSpacingY = 1.0f;
    public float formationOffsetX = 2.5f; // 相对 spawnCenter.x 的水平偏移，用于靠右/靠左
    public GameObject formationEnemyPrefab; // 指定编队敌人类型（为空则自动选择）

    [Header("编队连续生成")]
    public bool continuousFormation = true; // 关闭波次，持续出编队
    public float formationInterval = 2.0f;  // 连续编队间隔秒
    public bool formationAlignRight = true; // 是否贴右侧
    public float formationRightMargin = 0.3f; // 贴右侧时与右边界的留白
    
    [Header("敌人配置")]
    public EnemyConfig[] enemyConfigs;
    
    [Header("对象池设置")]
    public bool useObjectPooling = false;
    public int poolSize = 20;
    
    [Header("调试设置")]
    public bool showDebugInfo = true;
    public bool showSpawnArea = true;
    
    private float nextSpawnTime;
    private int currentWave = 1;
    private int enemiesSpawnedThisWave;
    private bool isWaveActive = true;
    private float waveEndTime;
    private Transform enemyContainer;
    
    // 对象池相关
    private Dictionary<string, Queue<GameObject>> enemyPools;
    private Dictionary<string, GameObject> enemyPrefabMap;

    public enum FormationType { Grid, Line, Column }

    [System.Serializable]
    public class EnemyConfig
    {
        public GameObject prefab;
        public float spawnWeight = 1f; // 生成权重
        public int minWave = 1; // 最小出现波次
        public EnemyController.MovementPattern movementPattern;
        public float moveSpeed = 3f;
        public int health = 3;
        public bool canAttack = true;
        public float fireRate = 1f;
    }
    
    void Awake()
    {
        // 单例模式初始化
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    // --- 编队相关 ---
    void SpawnFormationWave()
    {
        GameObject prefab = formationEnemyPrefab != null ? formationEnemyPrefab : SelectEnemyPrefab();
        if (prefab == null) return;

        List<Vector3> positions = GetFormationPositions();
        int totalToSpawn = Mathf.Min(positions.Count, enemiesPerWave > 0 ? enemiesPerWave : positions.Count);

        int spawned = 0;
        for (int i = 0; i < positions.Count && spawned < totalToSpawn; i++)
        {
            if (enemyContainer.childCount >= maxEnemiesOnScreen) break;
            GameObject enemy = GetEnemyAtPosition(prefab, positions[i]);
            ConfigureEnemy(enemy);
            EnemyController controller = enemy.GetComponent<EnemyController>();
            if (controller != null) controller.SetEnemySpawner(this);
            spawned++;
        }

        enemiesSpawnedThisWave = spawned;
    }

    List<Vector3> GetFormationPositions()
    {
        List<Vector3> pos = new List<Vector3>();
        Vector3 origin = GetFormationOrigin();

        switch (formationType)
        {
            case FormationType.Grid:
                for (int r = 0; r < formationRows; r++)
                {
                    for (int c = 0; c < formationColumns; c++)
                    {
                        float x = (c - (formationColumns - 1) * 0.5f) * formationSpacingX;
                        float y = -(r * formationSpacingY);
                        pos.Add(origin + new Vector3(x, y, 0));
                    }
                }
                break;
            case FormationType.Line:
                for (int c = 0; c < formationColumns; c++)
                {
                    float x = (c - (formationColumns - 1) * 0.5f) * formationSpacingX;
                    pos.Add(origin + new Vector3(x, 0, 0));
                }
                break;
            case FormationType.Column:
                for (int r = 0; r < formationRows; r++)
                {
                    float y = -(r * formationSpacingY);
                    pos.Add(origin + new Vector3(0, y, 0));
                }
                break;
        }

        return pos;
    }

    Vector3 GetFormationOrigin()
    {
        float x = spawnCenter.x + formationOffsetX;
        if (formationAlignRight)
        {
            // 将编队靠右：起点基于生成区域右边界减去留白
            x = spawnCenter.x + (spawnWidth * 0.5f) - formationRightMargin;
        }
        return new Vector3(x, spawnCenter.y + spawnHeight, 0);
    }

    GameObject GetEnemyAtPosition(GameObject prefab, Vector3 position)
    {
        if (!useObjectPooling)
        {
            return Instantiate(prefab, position, Quaternion.identity, enemyContainer);
        }

        string prefabName = prefab.name;
        if (enemyPools.ContainsKey(prefabName) && enemyPools[prefabName].Count > 0)
        {
            GameObject enemy = enemyPools[prefabName].Dequeue();
            enemy.transform.position = position;
            enemy.transform.rotation = Quaternion.identity;
            enemy.SetActive(true);
            return enemy;
        }

        return Instantiate(prefab, position, Quaternion.identity, enemyContainer);
    }

    // 连续编队生成：每隔 formationInterval 生成一整队
    void HandleContinuousFormationSpawn()
    {
        // 计划生成数量
        int planned = Mathf.Max(1, formationRows * formationColumns);

        // 以激活的敌人数为准，决定还能生成多少
        int activeCount = GetActiveEnemyCount();
        int allowed = Mathf.Max(0, maxEnemiesOnScreen - activeCount);
        if (allowed <= 0) return;

        if (Time.time >= nextSpawnTime)
        {
            // 连续编队模式下按“可容纳数量”生成，最多不超过完整队形
            int backup = enemiesPerWave;
            enemiesPerWave = Mathf.Min(planned, allowed);

            SpawnFormationWave();

            // 还原以避免影响其他模式
            enemiesPerWave = backup;

            nextSpawnTime = Time.time + formationInterval;
            if (showDebugInfo)
            {
                Debug.Log($"连续编队生成：计划{planned} 实际{enemiesPerWave}，激活={activeCount}/{maxEnemiesOnScreen}，下次{formationInterval}s");
            }
        }
    }

    // 统计当前激活中的敌人数（避免对象池中未激活的子物体影响上限判断）
    int GetActiveEnemyCount()
    {
        int count = 0;
        for (int i = 0; i < enemyContainer.childCount; i++)
        {
            Transform t = enemyContainer.GetChild(i);
            if (t.gameObject.activeInHierarchy) count++;
        }
        return count;
    }
    
    void Start()
    {
        // 创建敌人容器
        GameObject container = GameObject.Find("Enemies");
        if (container == null)
        {
            container = new GameObject("Enemies");
        }
        enemyContainer = container.transform;
        
        // 创建子弹容器
        GameObject bulletContainer = GameObject.Find("EnemyBullets");
        if (bulletContainer == null)
        {
            bulletContainer = new GameObject("EnemyBullets");
        }
        
        // 如果没有配置敌人预制体，创建默认的
        if (enemyPrefabs == null || enemyPrefabs.Length == 0)
        {
            CreateDefaultEnemyPrefabs();
        }
        
        // 初始化对象池
        InitializeObjectPool();
        
        // 设置初始生成时间
        nextSpawnTime = Time.time + 2f; // 游戏开始2秒后开始生成
        
        Debug.Log($"敌人生成器已初始化: 生成速度={spawnRate}, 最大敌人数={maxEnemiesOnScreen}");
    }
    
    void Update()
    {
        // 优先：连续编队生成（用户需求）
        if (useFormation && !useWaveSystem && continuousFormation)
        {
            HandleContinuousFormationSpawn();
            return;
        }

        if (useWaveSystem)
        {
            HandleWaveSystem();
        }
        else
        {
            HandleContinuousSpawn();
        }
        
        if (showDebugInfo)
        {
            int currentEnemyCount = enemyContainer.childCount;
            // Debug.Log($"当前波次: {currentWave}, 屏幕敌人数: {currentEnemyCount}, 下次生成: {nextSpawnTime - Time.time:F1}s");
        }
    }
    
    void HandleWaveSystem()
    {
        if (isWaveActive)
        {
            // 若开启编队，开波即一次性生成整队
            if (useFormation && enemiesSpawnedThisWave == 0)
            {
                SpawnFormationWave();
                isWaveActive = false;
                waveEndTime = Time.time + timeBetweenWaves;
                Debug.Log($"第{currentWave}波(编队)结束，等待{timeBetweenWaves}秒开始下一波");
                return;
            }

            // 兼容旧的逐个生成逻辑
            if (Time.time >= nextSpawnTime && enemiesSpawnedThisWave < enemiesPerWave)
            {
                if (enemyContainer.childCount < maxEnemiesOnScreen)
                {
                    SpawnEnemy();
                    enemiesSpawnedThisWave++;
                    nextSpawnTime = Time.time + spawnRate;
                }
            }

            if (enemiesSpawnedThisWave >= enemiesPerWave)
            {
                isWaveActive = false;
                waveEndTime = Time.time + timeBetweenWaves;
                Debug.Log($"第{currentWave}波结束，等待{timeBetweenWaves}秒开始下一波");
            }
        }
        else
        {
            if (Time.time >= waveEndTime)
            {
                StartNextWave();
            }
        }
    }
    
    void HandleContinuousSpawn()
    {
        if (Time.time >= nextSpawnTime && enemyContainer.childCount < maxEnemiesOnScreen)
        {
            SpawnEnemy();
            nextSpawnTime = Time.time + spawnRate;
        }
    }
    
    void StartNextWave()
    {
        currentWave++;
        enemiesSpawnedThisWave = 0;
        isWaveActive = true;
        
        // 增加难度（针对逐个生成模式）
        spawnRate = Mathf.Max(0.5f, spawnRate - spawnRateIncrease);
        
        if (useFormation)
        {
            // 直接按编队一次性生成，然后进入波次间隔
            SpawnFormationWave();
            isWaveActive = false;
            waveEndTime = Time.time + timeBetweenWaves;
            Debug.Log($"开始第{currentWave}波(编队)，一次性生成 {enemiesSpawnedThisWave} 个；进入间隔 {timeBetweenWaves}s");
            return;
        }
        
        Debug.Log($"开始第{currentWave}波(逐个生成)，生成速度: {spawnRate}");
    }
    
    void SpawnEnemy()
    {
        GameObject enemyPrefab = SelectEnemyPrefab();
        if (enemyPrefab == null) return;
        
        GameObject enemy = GetPooledEnemy(enemyPrefab);
        
        // 配置敌人属性
        ConfigureEnemy(enemy);
        
        // 设置对象池回调
        EnemyController enemyController = enemy.GetComponent<EnemyController>();
        if (enemyController != null)
        {
            enemyController.SetEnemySpawner(this);
        }
        
        if (showDebugInfo)
        {
            Debug.Log($"生成敌人: {enemy.name} 在位置 {enemy.transform.position}");
        }
    }
    
    GameObject SelectEnemyPrefab()
    {
        if (enemyConfigs != null && enemyConfigs.Length > 0)
        {
            // 根据权重和波次选择敌人
            float totalWeight = 0f;
            
            foreach (var config in enemyConfigs)
            {
                if (currentWave >= config.minWave)
                {
                    totalWeight += config.spawnWeight;
                }
            }
            
            if (totalWeight > 0)
            {
                float randomValue = Random.Range(0f, totalWeight);
                float currentWeight = 0f;
                
                foreach (var config in enemyConfigs)
                {
                    if (currentWave >= config.minWave)
                    {
                        currentWeight += config.spawnWeight;
                        if (randomValue <= currentWeight)
                        {
                            return config.prefab;
                        }
                    }
                }
            }
        }
        
        // 备用方案：从数组中随机选择
        if (enemyPrefabs != null && enemyPrefabs.Length > 0)
        {
            return enemyPrefabs[Random.Range(0, enemyPrefabs.Length)];
        }
        
        return null;
    }
    
    Vector3 GetRandomSpawnPosition()
    {
        float randomX = Random.Range(-spawnWidth / 2f, spawnWidth / 2f);
        return new Vector3(spawnCenter.x + randomX, spawnCenter.y + spawnHeight, 0);
    }
    
    void ConfigureEnemy(GameObject enemy)
    {
        EnemyController controller = enemy.GetComponent<EnemyController>();
        if (controller == null) return;
        
        // 查找对应的配置
        EnemyConfig config = null;
        if (enemyConfigs != null)
        {
            foreach (var cfg in enemyConfigs)
            {
                if (cfg.prefab == enemy || cfg.prefab.name == enemy.name.Replace("(Clone)", ""))
                {
                    config = cfg;
                    break;
                }
            }
        }
        
        if (config != null)
        {
            // 应用配置
            controller.movementPattern = config.movementPattern;
            controller.moveSpeed = config.moveSpeed;
            controller.health = config.health;
            controller.maxHealth = config.health;
            controller.canAttack = config.canAttack;
            controller.fireRate = config.fireRate;
        }
        
        // 根据波次调整属性
        float waveMultiplier = 1f + (currentWave - 1) * 0.2f;
        controller.health = Mathf.RoundToInt(controller.health * waveMultiplier);
        controller.maxHealth = controller.health;
        controller.moveSpeed *= (1f + (currentWave - 1) * 0.1f);
    }
    
    void CreateDefaultEnemyPrefabs()
    {
        // 创建基础敌人
        GameObject basicEnemy = new GameObject("BasicEnemy");
        basicEnemy.AddComponent<EnemyController>();
        
        // 创建快速敌人
        GameObject fastEnemy = new GameObject("FastEnemy");
        EnemyController fastController = fastEnemy.AddComponent<EnemyController>();
        fastController.moveSpeed = 5f;
        fastController.movementPattern = EnemyController.MovementPattern.SineWave;
        
        enemyPrefabs = new GameObject[] { basicEnemy, fastEnemy };
        
        // 创建敌人配置
        enemyConfigs = new EnemyConfig[]
        {
            new EnemyConfig
            {
                prefab = basicEnemy,
                spawnWeight = 3f,
                minWave = 1,
                movementPattern = EnemyController.MovementPattern.StraightDown,
                moveSpeed = 3f,
                health = 3,
                canAttack = true,
                fireRate = 2f
            },
            new EnemyConfig
            {
                prefab = fastEnemy,
                spawnWeight = 1f,
                minWave = 3,
                movementPattern = EnemyController.MovementPattern.SineWave,
                moveSpeed = 5f,
                health = 2,
                canAttack = true,
                fireRate = 1.5f
            }
        };
        
        Debug.Log("已创建默认敌人预制体和配置");
    }
    
    // 公共方法：手动生成敌人
    public void SpawnEnemyAtPosition(Vector3 position)
    {
        GameObject enemyPrefab = SelectEnemyPrefab();
        if (enemyPrefab != null)
        {
            GameObject enemy = Instantiate(enemyPrefab, position, Quaternion.identity, enemyContainer);
            ConfigureEnemy(enemy);
        }
    }
    
    // 公共方法：设置生成速度
    public void SetSpawnRate(float rate)
    {
        spawnRate = Mathf.Max(0.1f, rate);
        Debug.Log($"生成速度已设置为: {spawnRate}");
    }
    
    // 公共方法：获取当前波次
    public int GetCurrentWave()
    {
        return currentWave;
    }
    
    void OnDrawGizmos()
    {
        if (showSpawnArea)
        {
            // 绘制生成区域
            Gizmos.color = Color.cyan;
            Vector3 center = new Vector3(spawnCenter.x, spawnCenter.y + spawnHeight, 0);
            Vector3 size = new Vector3(spawnWidth, 0.5f, 0);
            Gizmos.DrawWireCube(center, size);
            
            // 绘制生成点示例
            Gizmos.color = Color.yellow;
            for (int i = 0; i < 5; i++)
            {
                Vector3 samplePos = GetRandomSpawnPosition();
                Gizmos.DrawWireSphere(samplePos, 0.2f);
            }
        }
    }
    
    // 对象池相关方法
    void InitializeObjectPool()
    {
        if (!useObjectPooling) return;
        
        enemyPools = new Dictionary<string, Queue<GameObject>>();
        enemyPrefabMap = new Dictionary<string, GameObject>();
        
        // 为每种敌人类型创建对象池
        if (enemyPrefabs != null)
        {
            foreach (GameObject prefab in enemyPrefabs)
            {
                if (prefab != null)
                {
                    string prefabName = prefab.name;
                    enemyPools[prefabName] = new Queue<GameObject>();
                    enemyPrefabMap[prefabName] = prefab;
                    
                    // 预创建敌人对象
                    for (int i = 0; i < poolSize / enemyPrefabs.Length; i++)
                    {
                        GameObject enemy = Instantiate(prefab, enemyContainer);
                        enemy.SetActive(false);
                        enemyPools[prefabName].Enqueue(enemy);
                    }
                }
            }
        }
        
        Debug.Log($"敌人对象池已初始化，总池大小: {poolSize}");
    }
    
    GameObject GetPooledEnemy(GameObject prefab)
    {
        if (!useObjectPooling)
        {
            return Instantiate(prefab, GetRandomSpawnPosition(), Quaternion.identity, enemyContainer);
        }
        
        string prefabName = prefab.name;
        
        if (enemyPools.ContainsKey(prefabName) && enemyPools[prefabName].Count > 0)
        {
            GameObject enemy = enemyPools[prefabName].Dequeue();
            enemy.transform.position = GetRandomSpawnPosition();
            enemy.transform.rotation = Quaternion.identity;
            enemy.SetActive(true);
            return enemy;
        }
        
        // 如果池中没有可用对象，创建新的
        return Instantiate(prefab, GetRandomSpawnPosition(), Quaternion.identity, enemyContainer);
    }
    
    public void ReturnEnemyToPool(GameObject enemy)
    {
        if (!useObjectPooling)
        {
            Destroy(enemy);
            return;
        }
        
        // 根据敌人名称确定类型
        string enemyType = enemy.name.Replace("(Clone)", "");
        
        if (enemyPools.ContainsKey(enemyType))
        {
            enemy.SetActive(false);
            enemy.transform.SetParent(enemyContainer);
            enemyPools[enemyType].Enqueue(enemy);
        }
        else
        {
            Destroy(enemy);
        }
    }
    
    public void EnableObjectPooling(bool enable)
    {
        useObjectPooling = enable;
        if (enable && enemyPools == null)
        {
            InitializeObjectPool();
        }
        Debug.Log($"敌人对象池已{(enable ? "启用" : "禁用")}");
    }
}